package com.zhiche.wms.service.inbound.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.domain.mapper.base.StorehouseMapper;
import com.zhiche.wms.domain.mapper.certification.CertificationInfoMapper;
import com.zhiche.wms.domain.mapper.inbound.*;
import com.zhiche.wms.domain.mapper.stock.StockDetailMapper;
import com.zhiche.wms.domain.model.base.StoreLocation;
import com.zhiche.wms.domain.model.certification.CertificationInfo;
import com.zhiche.wms.domain.model.inbound.*;
import com.zhiche.wms.domain.model.otm.OtmOrderRelease;
import com.zhiche.wms.domain.model.stock.Sku;
import com.zhiche.wms.domain.model.stock.Stock;
import com.zhiche.wms.domain.model.stock.StockDetail;
import com.zhiche.wms.domain.model.stock.StockProperty;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.inbound.InboundPutawayDTO;
import com.zhiche.wms.dto.inbound.LocChangeDTO;
import com.zhiche.wms.service.base.IStoreLocationService;
import com.zhiche.wms.service.dto.CancleInboundVO;
import com.zhiche.wms.service.inbound.IInboundPutawayLineService;
import com.zhiche.wms.service.otm.IOtmOrderReleaseService;
import com.zhiche.wms.service.stock.ISkuService;
import com.zhiche.wms.service.stock.IStockService;
import com.zhiche.wms.service.sys.IUserService;
import com.zhiche.wms.service.utils.CommonMethod;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.*;

@Service
public class InboundPutawayLineServiceImpl extends ServiceImpl<InboundPutawayLineMapper, InboundPutawayLine> implements IInboundPutawayLineService {
    @Autowired
    private IStockService stockService;
    @Autowired
    private IOtmOrderReleaseService releaseService;
    @Autowired
    private IStoreLocationService locationService;
    @Autowired
    InboundPutawayHeaderMapper inboundPutawayHeaderMapper;
    @Autowired
    InboundPutawayLineMapper inboundPutawayLineMapper;
    @Autowired
    StorehouseMapper storehouseMapper;
    @Autowired
    private IUserService userService;
    @Autowired
    private CertificationInfoMapper certificationInfoMapper;
    @Autowired
    private ISkuService iSkuService;
    @Autowired
    private InboundNoticeLineMapper inboundNoticeLineMapper;
    @Autowired
    private InboundNoticeHeaderMapper inboundNoticeHeaderMapper;
    @Autowired
    private WMSCancleInboundMapper wmsCancleInboundMapper;
    @Autowired
    private StockDetailMapper stockDetailMapper;

    private static final Logger LOGGER = LoggerFactory.getLogger(InboundPutawayLineServiceImpl.class);

    public InboundPutawayDTO getPutWaylineById(Long id) {
        InboundPutawayDTO inboundPutawayDTO = null;
        try {
            inboundPutawayDTO = this.baseMapper.getPutWayByLineId(id);
        } catch (BaseException e) {
            LOGGER.error("Service:\t" + e.toString());
            throw new BaseException("查询入库信息出错");
        } catch (Exception e) {
            LOGGER.error("Service:\t" + e.toString());
            throw new BaseException("查询出库信息出错");
        }
        return inboundPutawayDTO;
    }

    public Page<InboundPutawayDTO> queryLinePage(Page<InboundPutawayDTO> page) {
        Map<String, Object> condition = page.getCondition();
        if (condition != null && !condition.isEmpty()) {
            EntityWrapper<InboundPutawayDTO> ew = buildCondition(condition);
            List<InboundPutawayDTO> inboundPutawayDTOS = this.baseMapper.queryPutWayListByPage(page, ew);
            if (CollectionUtils.isNotEmpty(inboundPutawayDTOS)) {
                page.setRecords(inboundPutawayDTOS);
            }
        }
        return page;
    }

    private EntityWrapper<InboundPutawayDTO> buildCondition (Map<String, Object> condition) {
        EntityWrapper<InboundPutawayDTO> ew = new EntityWrapper<>();
        Object vinNO = condition.get("vinNo");
        Object materielId = condition.get("materielId");
        Object startDate = condition.get("startDate");
        Object endDate = condition.get("endDate");
        Object houseId = condition.get("houseId");
        if (!Objects.isNull(materielId)) ew.like("materiel_id", materielId.toString());
        if (!Objects.isNull(houseId)) ew.eq("store_house_id", houseId.toString());
        if (startDate != null && StringUtils.isNotBlank(startDate.toString())) {
            ew.ge("gmt_create", startDate);
        }
        if (endDate != null && StringUtils.isNotBlank(endDate.toString())) {
            ew.le("gmt_create", endDate);
        }
        if (condition.get("keyStatus") != null && StringUtils.isNotBlank(condition.get("keyStatus").toString())) {
            ew.eq("key_status", condition.get("keyStatus").toString());
        }
        if (condition.get("certificatStatus") != null && StringUtils.isNotBlank(condition.get("certificatStatus").toString())) {
            ew.eq("certificatStatus", condition.get("certificatStatus").toString());
        }
        if (!Objects.isNull(vinNO) && StringUtils.isNotEmpty(vinNO.toString().trim())) {
            String vin = vinNO.toString();
            List<String> vins = Arrays.asList(CommonMethod.setVins(vin));
            ew.andNew().in("lot_no1", vins).or().like("lot_no1", vin);
        }
        ew.orderBy("id", false);
        return ew;
    }

    @Override
    public List<InboundPutawayDTO> queryExportData(Map<String, String> condition) {
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        if (StringUtils.isBlank(condition.get("houseId"))) {
            throw new BaseException("仓库信息不能为空");
        }
        EntityWrapper<InboundPutawayDTO> ew = new EntityWrapper<>();
        ew.eq("store_house_id", condition.get("houseId"));

        if (StringUtils.isNotBlank(condition.get("materielId"))) {
            ew.like("materiel_id", condition.get("materielId"));
        }
        if (StringUtils.isNotBlank(condition.get("keyStatus"))) {
            ew.eq("key_status", condition.get("keyStatus"));
        }
        if (StringUtils.isNotBlank(condition.get("startDate"))) {
            ew.ge("gmt_create", condition.get("startDate"));
        }
        if (StringUtils.isNotBlank(condition.get("endDate"))) {
            ew.le("gmt_create", condition.get("endDate"));
        }
        if (StringUtils.isNotBlank(condition.get("vinNo"))) {
            String vin = condition.get("vinNo").toString();
           /* List<String> vins = Arrays.asList(vin.split(","));*/
            List<String> vins = Arrays.asList(CommonMethod.setVins(vin));
            ew.andNew().in("lot_no1", vins).or().like("lot_no1", vin);
        }
        ew.orderBy("id", false);
        return baseMapper.selectExportData(ew);
    }

    /**
     * 领取钥匙时获取信息
     */
    @Override
    public InboundPutawayDTO getReceiveKeyInfo(Map<String, String> condition) {
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        String lotNo1 = condition.get("lotNo1");
        String houseId = condition.get("houseId");
        if (StringUtils.isBlank(lotNo1)) {
            throw new BaseException("车架号信息不能为空");
        }
        if (StringUtils.isBlank(houseId)) {
            throw new BaseException("仓库id不能为空");
        }
        EntityWrapper<OtmOrderRelease> oorEW = new EntityWrapper<>();
        oorEW.eq("qr_code", lotNo1)
                .ne("status", TableStatusEnum.STATUS_50.getCode())
                .orderBy("id", false);
        OtmOrderRelease release = releaseService.selectOne(oorEW);
        if (release != null) {
            lotNo1 = release.getVin();
        }
        // 查询入库信息
        EntityWrapper<InboundPutawayLine> ew = new EntityWrapper<>();
        ew.eq("lot_no1", lotNo1)
                .eq("storeHouseId", houseId)
                .orderBy("gmt_create", false)
                .orderBy("id", false);
        List<InboundPutawayDTO> result = this.baseMapper.getLineWithHouseId(ew);
        if (CollectionUtils.isEmpty(result)) {
            throw new BaseException("未查询到车架号:" + lotNo1 + "入库信息");
        }
        if (result.size() > 1) {
            throw new BaseException("查询到车架号:" + lotNo1 + "多条入库");
        }
        InboundPutawayDTO putawayDTO = result.get(0);
        //获取调整后最终库位信息
        StockProperty property = new StockProperty();
        property.setOwnerId(putawayDTO.getOwnerId());
        property.setMaterielId(putawayDTO.getMaterielId());
        property.setLotNo1(putawayDTO.getLotNo1());
        property.setStoreHouseId(putawayDTO.getStoreHouseId());
        property.setUom(putawayDTO.getUom());
        List<Stock> stockList = stockService.queryStockList(property);
        if (CollectionUtils.isEmpty(stockList)) {
            throw new BaseException("未查询到对应库存信息");
        }
        Stock stock = stockList.get(0);
        StoreLocation location = locationService.selectLocationByLocationId(stock.getLocationId());
        if (location != null) {
            putawayDTO.setAreaCode(location.getStoreAreaName());
            putawayDTO.setAreaName(location.getStoreAreaName());
            putawayDTO.setLocationCode(location.getCode());
            putawayDTO.setLocationName(location.getName());
        }
        return putawayDTO;
    }

    /**
     * 领取钥匙
     */
    @Override
    public void updateReceiveKey(Map<String, String> condition) {
        if (condition == null || condition.isEmpty() || !condition.containsKey("putawayLineIds")) {
            throw new BaseException("参数不能为空");
        }

        String putawayLineIds = condition.get("putawayLineIds");
        if (StringUtils.isBlank(putawayLineIds)) {
            throw new BaseException("入库明细参数不为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }

        List<String> messages = new ArrayList<>();
        String[] LineIds = putawayLineIds.split(",");
        for (String putawayLineId : LineIds) {

            InboundPutawayLine line = selectById(Long.valueOf(putawayLineId));
            if (TableStatusEnum.STATUS_20.getCode().equals(line.getKeyStatus())) {
                messages.add(line.getLotNo1() + "已经领取钥匙");
                continue;
            }
            InboundPutawayLine newLine = new InboundPutawayLine();
            newLine.setId(line.getId());
            newLine.setKeyStatus(TableStatusEnum.STATUS_20.getCode());
            newLine.setTakeKeyUser(loginUser.getName());
            newLine.setTakeKeyDate(new Date());
            updateById(newLine);
        }

        if (messages.size() > 0) {
            String message = "";
            for (String s : messages) {
                message += s + ",";
            }
            throw new BaseException(1,message);
        }


    }

    /**
     * 领取钥匙时打印二维码
     */
    @Override
    public InboundPutawayDTO getKeyPrintInfo(Map<String, String> condition) {
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        String lotNo1 = condition.get("lotNo1");
        if (StringUtils.isBlank(lotNo1)) {
            throw new BaseException("车架号信息不能为空");
        }
        String img = null;
        try {
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
            Hashtable<EncodeHintType, String> hints = new Hashtable<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = multiFormatWriter.encode(lotNo1, BarcodeFormat.QR_CODE, 60, 60, hints);
            BufferedImage image = InboundNoticeLineServiceImpl.toBufferedImage(bitMatrix);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);
            //Base64 base64 = new Base64();
            BASE64Encoder base64 = new BASE64Encoder();
            img = base64.encode(os.toByteArray());
        } catch (Exception e) {
            LOGGER.error("InboundPutawayLineServiceImpl.getKeyPrintInfo:[ERROR]" + e.toString());
            throw new BaseException("生成二维码错误");
        }
        InboundPutawayDTO putawayDTO = new InboundPutawayDTO();
        putawayDTO.setImgBase64(img);
        putawayDTO.setLotNo1(lotNo1);
        return putawayDTO;
    }

    /**
     * 查询调整记录
     */
    @Override
    public Page<LocChangeDTO> queryChangLocList(Page<LocChangeDTO> page) {
        if (page == null) {
            throw new BaseException("分页参数不能为空");
        }
        Map<String, Object> condition = page.getCondition();
        EntityWrapper<LocChangeDTO> ew = buildLocListCondition(condition);
        List<LocChangeDTO> rec = baseMapper.queryChangeLocList(page, ew);
        page.setRecords(rec);
        return page;
    }

    /**
     * 导出调整记录
     */
    @Override
    public List<LocChangeDTO> queryExportLocList(Map<String, Object> condition) {
        EntityWrapper<LocChangeDTO> ew = buildLocListCondition(condition);
        return baseMapper.queryExportLocList(ew);
    }

    @Override
    public boolean queryKeyStatus (Map<String, String> condition) {
        if (StringUtils.isEmpty(condition.get("vin"))) {
            throw new BaseException("车架号为空");
        }
        Wrapper<InboundPutawayLine> ew = new EntityWrapper<>();
        ew.eq("ipl.lot_no1", condition.get("vin"));
        ew.eq("ws.id", "10014");
        ew.orderBy("ipl.gmt_modified", false);
        List<InboundPutawayLine> inboundPutawayLine = baseMapper.queryKeyStatus(ew);
        if (CollectionUtils.isEmpty(inboundPutawayLine)) {
            throw new BaseException("未找到【" + condition.get("vin") + "】车架号对应的信息");
        }

        String certificationStatus = TableStatusEnum.STATUS_10.getCode();
        CertificationInfo queryParam = new CertificationInfo();
        queryParam.setVin(condition.get("vin"));
        CertificationInfo certificationInfo = certificationInfoMapper.selectOne(queryParam);
        if (null != certificationInfo) {
            certificationStatus = certificationInfo.getCertificatStatus();
        }
        if (TableStatusEnum.STATUS_20.getCode().equals(inboundPutawayLine.get(0).getKeyStatus()) && !TableStatusEnum.STATUS_10.getCode().equals(certificationStatus)) {
            return true;
        }
        return false;
    }

    @Override
    public String giveOutCertificat (Map<String, String> condition) {
        if (condition == null || condition.isEmpty() || !condition.containsKey("putawayLineIds")) {
            throw new BaseException("参数不能为空");
        }
        String putawayLineIds = condition.get("putawayLineIds");
        if (StringUtils.isBlank(putawayLineIds)) {
            throw new BaseException("入库明细参数不为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        String[] lineIds = putawayLineIds.split(",");
        StringBuffer sb = new StringBuffer();
        List<InboundPutawayLine> inboundPutawayLines = inboundPutawayLineMapper.selectBatchIds(Arrays.asList(lineIds));
        for (InboundPutawayLine inboundPutawayLine : inboundPutawayLines){
            if(null == inboundPutawayLine.getCertificatNum()){
                sb.append("车架号:").append(inboundPutawayLine.getLotNo1()).append(":").append("没有领取记录，不能发放！");
            }else if(inboundPutawayLine.getCertificatNum() < 1){
                sb.append("车架号:").append(inboundPutawayLine.getLotNo1()).append(":").append("合格证已经发放过，请核对！");
            }else{
                InboundPutawayLine updateParam = new InboundPutawayLine();
                updateParam.setId(inboundPutawayLine.getId());
                updateParam.setGiveoutDate(new Date());
                updateParam.setGiveoutUser(loginUser.getName());
                updateParam.setCertificatNum(inboundPutawayLine.getCertificatNum()-1);
                updateParam.setCertificatStatus(TableStatusEnum.STATUS_30.getCode());
                inboundPutawayLineMapper.updateById(updateParam);
            }
        }
        return sb.toString();
    }

    @Override
    public String receiveOutCertificat (Map<String, String> condition) {
        if (condition == null || condition.isEmpty() || !condition.containsKey("putawayLineIds")) {
            throw new BaseException("参数不能为空");
        }
        String putawayLineIds = condition.get("putawayLineIds");
        if (StringUtils.isBlank(putawayLineIds)) {
            throw new BaseException("入库明细参数不为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        String[] lineIds = putawayLineIds.split(",");
        StringBuffer sb = new StringBuffer();
        List<InboundPutawayLine> inboundPutawayLines = inboundPutawayLineMapper.selectBatchIds(Arrays.asList(lineIds));
        for (InboundPutawayLine inboundPutawayLine : inboundPutawayLines) {
            if(null == inboundPutawayLine.getCertificatNum()){
                inboundPutawayLine.setCertificatNum(0);
            }
            if (inboundPutawayLine.getCertificatNum() > 0) {
                sb.append("车架号:").append(inboundPutawayLine.getLotNo1()).append(":合格证已经领取过，请核对！");
            } else {
                InboundPutawayLine updateParam = new InboundPutawayLine();
                updateParam.setId(inboundPutawayLine.getId());
                updateParam.setReceiveDate(new Date());
                updateParam.setReceiveUser(loginUser.getName());
                updateParam.setCertificatNum(inboundPutawayLine.getCertificatNum() + 1);
                updateParam.setCertificatStatus(TableStatusEnum.STATUS_20.getCode());
                inboundPutawayLineMapper.updateById(updateParam);
            }
        }
        return sb.toString();
    }

    @Override
    public List<InboundPutawayDTO> exportPutawayKeyData (Page<InboundPutawayDTO> page) {
        List<InboundPutawayDTO> inboundPutawayDTOS = new ArrayList<>();
        Map<String, Object> condition = page.getCondition();
        if (condition != null && !condition.isEmpty()) {
            EntityWrapper<InboundPutawayDTO> ew = buildCondition(condition);
            inboundPutawayDTOS = baseMapper.exportPutawayKeyData(ew);
        }
        if (inboundPutawayDTOS.size() > 10000) {
            throw new BaseException("导出数据大于限制数量【1W】在，筛选条件分批导出！");
        }
        return inboundPutawayDTOS;
    }

    @Override
    public List<String> wmsCancleInbound (Map<String, String> param) {
        List<String> reslut = new ArrayList<>();
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("未查询到登录用户");
        }
        if (null == param) {
            throw new BaseException("参数不能为空");
        }
        if (StringUtils.isEmpty(param.get("putawayLineIds"))) {
            throw new BaseException("取消入库主键参数id为空");
        }

        if (StringUtils.isEmpty(param.get("storeHouseId"))) {
            throw new BaseException("取消入库仓库为空");
        }
        String[] putawayLineIds = param.get("putawayLineIds").split(",");

        //1、入库记录状态更新为50
        List<CancleInboundVO> updateResult = updatePutawayStatus(putawayLineIds,param.get("storeHouseId"));
        StringBuffer sb = new StringBuffer();
        for (CancleInboundVO cancleInboundVO : updateResult) {
            try {
                //2、修改库存
                updateStockQty(cancleInboundVO);

                //3、修改入库通知单状态
                updateNoticeStatus(cancleInboundVO);

                //4、修改运单表状态
                updateReleaseStatus(cancleInboundVO);

                //5、记录操作日志
                insertCancleInboundLog(cancleInboundVO, loginUser.getName(), param.get("sourceType"));
            } catch (BaseException be) {
                sb.append("车架号:").append(cancleInboundVO.getVin()).append(": " + be.getMessage());

            } catch (Exception e) {
                LOGGER.error("取消入库错误信息{}",e.getMessage());
                sb.append("车架号:").append(cancleInboundVO.getVin()).append(": 系统异常，请稍后重试!");
            }
            if(StringUtils.isNotEmpty(sb)){
                reslut.add(sb.toString());
            }
        }
        return reslut;
    }

    /**
     * 记录取消入库日志
     */
    private void insertCancleInboundLog (CancleInboundVO cancleInboundVO, String name, String sourceType) {
        WMSCancleInbound wmsCancleInbound = new WMSCancleInbound();
        wmsCancleInbound.setUserCreate(name);
        wmsCancleInbound.setGmtCreate(new Date());
        wmsCancleInbound.setSourceType(sourceType);
        wmsCancleInbound.setVin(cancleInboundVO.getVin());
        wmsCancleInbound.setReleaseGid(cancleInboundVO.getReleaseGid());
        wmsCancleInbound.setShipmentGid(cancleInboundVO.getShipmentGid());
        wmsCancleInbound.setReleationId(cancleInboundVO.getPutWayLineId());
        wmsCancleInbound.setHouseId(String.valueOf(cancleInboundVO.getHouseId()));
        wmsCancleInboundMapper.insert(wmsCancleInbound);
    }

    /**
     * 修改运单表的状态
     */
    private void updateReleaseStatus (CancleInboundVO cancleInboundVO) {
        //查询是否发运过
        EntityWrapper<OtmOrderRelease> releaseEw = new EntityWrapper<>();
        releaseEw.eq("release_gid", cancleInboundVO.getReleaseGid());
        releaseEw.eq("shipment_gid", cancleInboundVO.getShipmentGid());
        releaseEw.ne("status", TableStatusEnum.STATUS_50.getCode());
        List<OtmOrderRelease> otmOrderReleases = releaseService.selectList(releaseEw);
        if (CollectionUtils.isEmpty(otmOrderReleases)) {
            throw new BaseException("指令信息为空，请补指令");
        }
        if (otmOrderReleases.size() > 1) {
            throw new BaseException("有重复下发的指令");
        }

        OtmOrderRelease otmOrderRelease = otmOrderReleases.get(0);
        OtmOrderRelease updateParam = new OtmOrderRelease();
        updateParam.setId(otmOrderRelease.getId());
        if (null == otmOrderRelease.getShipDate()) {
            updateParam.setStatus(TableStatusEnum.STATUS_BS_CREATED.getCode());
        } else {
            updateParam.setStatus(TableStatusEnum.STATUS_BS_DISPATCH.getCode());
        }
        releaseService.updateById(updateParam);
    }

    /**
     * 修改入库通知单状态
     */
    private void updateNoticeStatus (CancleInboundVO cancleInboundVO) {
        //修改入库通知单状态
        EntityWrapper<InboundNoticeLine> updateLineParam = new EntityWrapper<>();
        updateLineParam.eq("id",cancleInboundVO.getNoticeLineId());
        updateLineParam.ne("status",TableStatusEnum.STATUS_50.getCode());
        InboundNoticeLine inboundNoticeLine = new InboundNoticeLine();
        inboundNoticeLine.setRemarks("取消入库");
        inboundNoticeLine.setInboundQty(BigDecimal.ZERO);
        inboundNoticeLine.setStatus(TableStatusEnum.STATUS_10.getCode());
        inboundNoticeLineMapper.update(inboundNoticeLine,updateLineParam);
        //修改出库通知单状态
        EntityWrapper<InboundNoticeLine> lineEw = new EntityWrapper<>();
        lineEw.eq("header_id", cancleInboundVO.getNoticeId());
        lineEw.ne("status", TableStatusEnum.STATUS_50.getCode());
        List<InboundNoticeLine> inboundNoticeLines = inboundNoticeLineMapper.selectList(lineEw);

        InboundNoticeHeader inboundHeaderQty = inboundNoticeHeaderMapper.selectById(cancleInboundVO.getNoticeId());
        InboundNoticeHeader inboundNoticeHeader = new InboundNoticeHeader();
        inboundNoticeHeader.setId(cancleInboundVO.getNoticeId());
        //查询通知单头对应的明细是否多条
        if (inboundNoticeLines.size() == 1) {
            inboundNoticeHeader.setStatus(TableStatusEnum.STATUS_10.getCode());
            inboundNoticeHeader.setInboundSumQty(BigDecimal.ZERO);
        } else {
            inboundNoticeHeader.setInboundSumQty(inboundHeaderQty.getInboundSumQty().subtract(BigDecimal.ONE));
            inboundNoticeHeader.setStatus(TableStatusEnum.STATUS_20.getCode());
        }
        inboundNoticeHeaderMapper.updateById(inboundNoticeHeader);

        cancleInboundVO.setReleaseGid(inboundNoticeLines.get(0).getLineSourceKey());
        cancleInboundVO.setShipmentGid(inboundNoticeHeaderMapper.selectById(cancleInboundVO.getNoticeId()).getSourceKey());
    }

    /**
     * 取消入库清理库存
     */
    private void updateStockQty (CancleInboundVO cancleInboundVO) {
        EntityWrapper<Stock> stockEw = new EntityWrapper<>();
        stockEw.eq("store_house_id", cancleInboundVO.getHouseId());
        stockEw.eq("sku_id", cancleInboundVO.getSkuId());
        if(null != cancleInboundVO.getUpdateLocationId()){
            stockEw.andNew().eq("location_id",cancleInboundVO.getLocationId()).or().eq("location_id",
                    cancleInboundVO.getUpdateLocationId());
        }else {
            stockEw.eq("location_id", cancleInboundVO.getLocationId());
        }

        Stock stock = stockService.selectOne(stockEw);
        if (null != stock && stock.getQty().compareTo(BigDecimal.ZERO) == 1) {
            Stock updateStock = new Stock();
            updateStock.setId(stock.getId());
            updateStock.setQty(stock.getQty().subtract(new BigDecimal(1)));
            stockService.updateById(updateStock);
            //清理库存明细

            EntityWrapper<StockDetail> sdEw = new EntityWrapper<>();
            sdEw.eq("stock_id", stock.getId());
            sdEw.eq("type", TableStatusEnum.STATUS_10.getCode());
            sdEw.gt("qty", 0);
            sdEw.groupBy("stock_id");
            List<StockDetail> stockDetails = stockDetailMapper.selectList(sdEw);
            if (CollectionUtils.isNotEmpty(stockDetails)) {
                EntityWrapper<StockDetail> stockDetailEw = new EntityWrapper<>();
                stockDetailEw.eq("id", stockDetails.get(0).getId());
                stockDetailEw.eq("type", TableStatusEnum.STATUS_10.getCode());
                StockDetail updateStockDetail = new StockDetail();
                updateStockDetail.setQty(BigDecimal.ZERO);
                stockDetailMapper.update(updateStockDetail, stockDetailEw);

            }

        }
    }

    /**
     * 入库记录状态更新为50
     *
     * @param putawayLineIds 入库记录明细id
     * @param storeHouseId
     */
    private List<CancleInboundVO> updatePutawayStatus (String[] putawayLineIds, String storeHouseId) {
        List<CancleInboundVO> result = new ArrayList<>();
        List<InboundPutawayLine> queryLineResult = baseMapper.selectBatchIds(Arrays.asList(putawayLineIds));
        if (CollectionUtils.isNotEmpty(queryLineResult)) {
            for (InboundPutawayLine inboundPutawayLine : queryLineResult) {
                CancleInboundVO cancleInboundVO = new CancleInboundVO();
                cancleInboundVO.setVin(inboundPutawayLine.getLotNo1());
                cancleInboundVO.setPutWayLineId(inboundPutawayLine.getId());
                cancleInboundVO.setLocationId(inboundPutawayLine.getLocationId());
                cancleInboundVO.setPutwayHeaderId(inboundPutawayLine.getHeaderId());
                cancleInboundVO.setNoticeLineId(inboundPutawayLine.getNoticeLineId());
                Sku sku = iSkuService.querySkuInfo(inboundPutawayLine.getLotNo1());
                if (null == sku) {
                    throw new BaseException("车架号信息id为空！");
                }

                EntityWrapper<Stock> stockEntityWrapper = new EntityWrapper<>();
                stockEntityWrapper.eq("store_house_id",storeHouseId);
                stockEntityWrapper.eq("sku_id",sku.getId());
                stockEntityWrapper.gt("qty",0);
                if(null != inboundPutawayLine.getUpdateLocationId()){
                    cancleInboundVO.setUpdateLocationId(inboundPutawayLine.getUpdateLocationId());
                    stockEntityWrapper.andNew().eq("location_id",inboundPutawayLine.getLocationId()).or().eq("location_id",
                            inboundPutawayLine.getUpdateLocationId());
                }else {
                    stockEntityWrapper.eq("location_id",inboundPutawayLine.getLocationId());
                }
                Stock stock = stockService.selectOne(stockEntityWrapper);
                if(null == stock){
                    throw new BaseException("当前仓库无库存，无法取消入库！");
                }
                cancleInboundVO.setSkuId(sku.getId());
                queryPutawayheader(cancleInboundVO);
                InboundPutawayLine updateLineParam = new InboundPutawayLine();
                updateLineParam.setId(inboundPutawayLine.getId());
                updateLineParam.setInboundStatus(TableStatusEnum.STATUS_50.getCode());
                baseMapper.updateById(updateLineParam);
                result.add(cancleInboundVO);
            }
        }
        return result;
    }

    /**
     * 修改入库记录明细状态
     *
     * @param cancleInboundVO 头表id
     */
    private CancleInboundVO queryPutawayheader (CancleInboundVO cancleInboundVO) {
        InboundPutawayHeader inboundPutawayHeader = inboundPutawayHeaderMapper.selectById(cancleInboundVO.getPutwayHeaderId());
        if (null == inboundPutawayHeader) {
            throw new BaseException("入库通知单头表信息为空");
        }
        cancleInboundVO.setHouseId(inboundPutawayHeader.getStoreHouseId());
        cancleInboundVO.setNoticeId(inboundPutawayHeader.getNoticeId());

        InboundPutawayHeader updateHeaderParam = new InboundPutawayHeader();
        updateHeaderParam.setId(inboundPutawayHeader.getId());
        updateHeaderParam.setStatus(TableStatusEnum.STATUS_50.getCode());
        inboundPutawayHeaderMapper.updateById(updateHeaderParam);

        return cancleInboundVO;
    }


    private EntityWrapper<LocChangeDTO> buildLocListCondition(Map<String, Object> condition) {
        if (condition == null || condition.isEmpty()) {
            throw new BaseException("参数不能为空");
        }
        Object houseId = condition.get("houseId");
        if (houseId == null || StringUtils.isBlank(houseId.toString())) {
            throw new BaseException("仓库id不能为空");
        }
        EntityWrapper<LocChangeDTO> ew = new EntityWrapper<>();
        ew.isNotNull("source_loc");
        ew.isNotNull("dest_loc");
        ew.eq("store_house_id", condition.get("houseId").toString());

        if (condition.get("ownerId") != null && StringUtils.isNotBlank(condition.get("ownerId").toString())) {
            ew.eq("owner_id", condition.get("ownerId").toString());
        }
        if (condition.get("startDate") != null && StringUtils.isNotBlank(condition.get("startDate").toString())) {
            ew.ge("gmt_create", condition.get("startDate").toString());
        }
        if (condition.get("endDate") != null && StringUtils.isNotBlank(condition.get("endDate").toString())) {
            ew.le("gmt_create", condition.get("endDate").toString());
        }
        if (condition.get("lotNo1") != null && StringUtils.isNotBlank(condition.get("lotNo1").toString())) {
            String vin = condition.get("lotNo1").toString();
            List<String> vins = Arrays.asList(CommonMethod.setVins(vin));
            ew.andNew().in("lot_no1", vins).or().like("lot_no1", vin);
        }
        ew.orderBy("lot_no1").orderBy("gmt_create",false);
        return ew;
    }
}